package com.yuda.tools.miscellaneous.controller;

import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.yuda.common.core.annotation.Excel;
import com.yuda.common.core.utils.StringUtils;
import com.yuda.common.core.utils.poi.ExcelUtil;
import com.yuda.common.core.web.domain.AjaxResult;
import com.yuda.tools.miscellaneous.dto.PaperCount;
import com.yuda.tools.miscellaneous.dto.SpartaExamConfig;
import com.yuda.tools.miscellaneous.dto.StatisticPaperCount;
import com.yuda.tools.miscellaneous.service.PaperCountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

@RestController
public class ImportPaperCountExcel {

    @Autowired
    private PaperCountService paperCountService;

    private static final List<StatisticPaperCount> listStatistic = new ArrayList<>();

    @GetMapping("/examUuids")
    public List<SpartaExamConfig> examUuids() {
        return paperCountService.listExamUuids();
    }


    @PostMapping("/export")
    public void export(HttpServletResponse response) throws Exception {
        ExcelWriter writer = cn.hutool.poi.excel.ExcelUtil.getWriter(true);

        writer.addHeaderAlias("kaoQu", "考区");
        writer.addHeaderAlias("subjectName", "科目");
        writer.addHeaderAlias("onlineNum", "线上人数");
        writer.addHeaderAlias("bagsOnLine", "线上袋数");
        writer.addHeaderAlias("offlineNum", "线下人数");
        writer.addHeaderAlias("bagsOffLine", "线下袋数");
        writer.setOnlyAlias(true);
        writer.write(listStatistic, true);
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=statistics.xlsx");
        ServletOutputStream out = response.getOutputStream();
        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);
    }

    @PostMapping("/read")
    public AjaxResult read(MultipartFile multipartFile) throws Exception {
        try {
            listStatistic.clear();
            ExcelUtil<PaperCount> excelUtil = new ExcelUtil<>(PaperCount.class);
            List<PaperCount> paperCounts = excelUtil.importExcel(multipartFile.getInputStream());
            //按照试卷类型分组 全国一卷  全国二卷  改革
            String[] baseSubjects = {"语文", "理数", "文数", "英语", "物理", "化学", "生物", "政治", "历史", "地理"};
            List<StatisticPaperCount> list = new ArrayList<>();
            Map<String, List<PaperCount>> collect = paperCounts.stream().collect(Collectors.groupingBy(PaperCount::getPaperType));
            for (String s : collect.keySet()) {
                List<PaperCount> pcList = collect.get(s);
                for (String subjectName : baseSubjects) {
                    //如果是全国一卷 语文，理数 文数 英语 理综(物理化学生物)  文综(政治历史地理) 理综文综 可以稍后统计，先统计出 最细的 然后在合并即可
                    int[] subjectsNums = new int[2]; //人数 第一个是线上人数 第二个是线下人数
                    int[] subjectsBags = new int[2]; //袋数 第一个线上袋数 第二个是线下袋数
                    StatisticPaperCount statisticPaperCount = new StatisticPaperCount();
                    statisticPaperCount.setKaoQu(s);
                    statisticPaperCount.setSubjectName(subjectName);
                    for (PaperCount pc : pcList) {
                        statisticPaperCount(pc, subjectsNums, subjectsBags, subjectName);
                    }
                    statisticPaperCount.setBagsOnLine(subjectsBags[0]);
                    statisticPaperCount.setBagsOffLine(subjectsBags[1]);
                    statisticPaperCount.setOnlineNum(subjectsNums[0]);
                    statisticPaperCount.setOfflineNum(subjectsNums[1]);
                    list.add(statisticPaperCount);
                }
            }

            //1卷 2 卷 改革卷在处理  1卷2卷把 小科目 合并为 文综理综
            List<StatisticPaperCount> list2 = new ArrayList<>();
            processWLz(list, list2);
            //导表
            list2.sort(Comparator.comparing(StatisticPaperCount::getKaoQu));
//        list2.forEach(x -> {
//            double d = Math.ceil(x.getBagsOffLine() * 51.0 / 50);
//            double d1 = Math.ceil(x.getBagsOnLine() * 31.0 / 30);
//            x.setBagsOffLine((int) d);
//            x.setBagsOnLine((int) d1);
//        });
            listStatistic.addAll(list2);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("失败");
        }
        return AjaxResult.success("成功");
    }

    private void processWLz(List<StatisticPaperCount> list, List<StatisticPaperCount> list2) {

        list.stream().filter(x -> x.getKaoQu().contains("一卷") && x.getSubjectName().contains("物理")).forEach(x -> {
            x.setSubjectName("理综");
            x.setKaoQu("全国一卷");
            list2.add(x);
        });
        list.stream().filter(x -> x.getKaoQu().contains("一卷") && x.getSubjectName().contains("政治")).forEach(x -> {
            x.setSubjectName("文综");
            x.setKaoQu("全国一卷");
            list2.add(x);
        });

        list.stream().filter(x -> x.getKaoQu().contains("二卷") && x.getSubjectName().contains("物理")).forEach(x -> {
            x.setSubjectName("理综");
            x.setKaoQu("全国二卷");
            list2.add(x);
        });
        list.stream().filter(x -> x.getKaoQu().contains("二卷") && x.getSubjectName().contains("政治")).forEach(x -> {
            x.setSubjectName("文综");
            x.setKaoQu("全国二卷");
            list2.add(x);
        });

        list.stream().filter(x -> x.getKaoQu().contains("改革") && x.getSubjectName().contains("理数")).forEach(x -> {
            x.setSubjectName("数学");
            x.setKaoQu("改革卷");
            list2.add(x);
        });

        setWLZ("一卷", list, list2);
        setWLZ("二卷", list, list2);

        list.stream().filter(x -> x.getKaoQu().contains("改革")).forEach(x -> {
            String subjectName = x.getSubjectName();
            if (subjectName.equals("文数")) {
                list2.stream().filter(y -> y.getKaoQu().contains("改革") && y.getSubjectName().contains("数学")).forEach(y -> {
                    y.setOnlineNum(y.getOnlineNum() + x.getOnlineNum());
                    y.setOfflineNum(y.getOfflineNum() + x.getOfflineNum());
                    y.setBagsOnLine(y.getBagsOnLine() + x.getBagsOnLine());
                    y.setBagsOffLine(y.getBagsOffLine() + x.getBagsOffLine());
                });
            } else if (!subjectName.equals("数学")) {
                list2.add(x);
            }
        });

    }

    private void setWLZ(String flag, List<StatisticPaperCount> list, List<StatisticPaperCount> list2) {
        list.stream().filter(x -> x.getKaoQu().contains(flag)).forEach(x -> {
            String subjectName = x.getSubjectName();
            if (subjectName.contains("化学") || subjectName.contains("生物")) {
//                list2.stream().filter(y -> y.getKaoQu().contains(flag) && y.getSubjectName().contains("理综")).forEach(y -> {
//                    y.setOnlineNum(y.getOnlineNum() + x.getOnlineNum());
//                    y.setOfflineNum(y.getOfflineNum() + x.getOfflineNum());
//                    y.setBagsOnLine(y.getBagsOnLine() + x.getBagsOnLine());
//                    y.setBagsOffLine(y.getBagsOffLine() + x.getBagsOffLine());
//                });
            } else if (subjectName.contains("历史") || subjectName.contains("地理")) {
//                list2.stream().filter(y -> y.getKaoQu().contains(flag) && y.getSubjectName().contains("文综")).forEach(y -> {
//                    y.setOnlineNum(y.getOnlineNum() + x.getOnlineNum());
//                    y.setOfflineNum(y.getOfflineNum() + x.getOfflineNum());
//                    y.setBagsOnLine(y.getBagsOnLine() + x.getBagsOnLine());
//                    y.setBagsOffLine(y.getBagsOffLine() + x.getBagsOffLine());
//                });
            } else if (!subjectName.equals("文综") && !subjectName.equals("理综")) {
                list2.add(x);
            }
        });
    }

    private void statisticPaperCount(PaperCount paperCount, int[] subjectsNums, int[] subjectsBags, String subjectName) throws IllegalAccessException {
        Class<? extends PaperCount> aClass = paperCount.getClass();
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            String name = field.getName();
            Excel annotation = field.getAnnotation(Excel.class);
            if (annotation == null || !annotation.name().contains(subjectName)) {
                continue;
            }
            Object o = field.get(paperCount);
            if (o instanceof String) {
                String fieldValue = (String) o;
                if (StringUtils.isEmpty(fieldValue)) {
                    fieldValue = "0";
                }
                if (name.startsWith("xs") && !name.endsWith("num")) {
                    subjectsNums[0] += Integer.parseInt(fieldValue);
                }
                if (name.startsWith("xx") && !name.endsWith("num")) {
                    subjectsNums[1] += Integer.parseInt(fieldValue);
                }
                if (name.startsWith("xs") && name.endsWith("num")) { //线上袋数
                    subjectsBags[0] += Integer.parseInt(fieldValue);
                }
                if (name.startsWith("xx") && name.endsWith("num")) { //线上袋数
                    subjectsBags[1] += Integer.parseInt(fieldValue);
                }
            }
        }
    }
}
